package org.xx.armory.commons;

import static org.apache.commons.lang3.CharUtils.isAsciiPrintable;
import static org.apache.commons.lang3.CharUtils.unicodeEscaped;

/**
 * 调试工具类，包含了一系列用于辅助调试的静态方法。
 *
 * @author Haart
 */
public class DebugUtils {

    private DebugUtils() {
        throw new UnsupportedOperationException();
    }

    /**
     * 比较两个字符串
     *
     * @param s1
     *         待比较的第一个字符串。
     * @param s2
     *         待比较的第二个字符串。
     * @return 比较结果。
     */
    public static StringComparisonResult compareString(
            String s1,
            String s2
    ) {
        if (s1 == null) {
            s1 = "";
        }
        if (s2 == null) {
            s2 = "";
        }
        final int len1 = s1.length();
        final int len2 = s2.length();

        for (int i = 0; i < len1 || i < len2; ++i) {
            final Character ch1 = i < len1 ? s1.charAt(i) : null;
            final Character ch2 = i < len2 ? s2.charAt(i) : null;

            if (ch1 != null || ch2 != null) {
                if (ch1 == null || ch2 == null || ch1.charValue() != ch2.charValue()) {
                    return StringComparisonResult.of(i, ch1, ch2);
                }
            }
        }

        return StringComparisonResult.NONE;
    }

    /**
     * 输出字符串，包括长度和每个字符的UNICODE码。
     *
     * <p>
     * 输出格式为：[size=字符串长度,每个字符或者每个字符的UNICODE码(如果该字符不是可打印的Ascii字符)] 。 如果字符串的长度超过{@code 10}，那么只输出前{@code 10}个字符，然后加上{@code "..."}
     * 。
     * </p>
     *
     * <p>
     * 此方法会把不可打印字符也通过UNICODE码的形式输出，所以可以清楚地区分出真正的空字符串和只包含了不可打印字符的字符串。
     * </p>
     *
     * <pre>
     * {@code
     * dumpString(null) = "[null]";
     * dumpString("") = "[size=0,]";
     * dumpString("\u2bef\u7734") = "[size=2,\\u2bef\\u7734]";
     * dumpString("a quick fox jumps over") = "[size=22,a quick fo...]";
     * }
     * </pre>
     *
     * @param s
     *         原始字符串。
     * @return 包含了长度和字符信息的字符串。
     * @see org.apache.commons.lang3.CharUtils#isAsciiPrintable(char)
     * @see org.apache.commons.lang3.CharUtils#unicodeEscaped(char)
     */
    public static String dumpString(String s) {
        final int MAX_LEN = 10;

        if (s == null) {
            return "[null]";
        } else if (s.isEmpty()) {
            return "[size=0,]";
        } else {
            final StringBuilder sb = new StringBuilder();
            for (int i = 0; i < s.length() && i < MAX_LEN; ++i) {
                final char ch = s.charAt(i);
                sb.append(isAsciiPrintable(ch) ? ch : unicodeEscaped(ch));
            }
            return "[size=" + s.length() + "," + sb.toString() + (s.length() > MAX_LEN ? "...]" : "]");
        }
    }
}
